import { Curve2 } from "../curve/Curve2";
import { Segment2 } from "../curve/Segment2";
import { Point2 } from "../point/Point2";

/**
 * 2D 多边形类
 * @class Polygon2
 */
export class Polygon2 {
    /** 边界 */
    private _boundary: Array<Curve2> = [];
    /** 孔洞 */
    private _holes: Array<Polygon2> = [];
    /** 父多边形 */
    private _parent: Polygon2 | null = null;
    /** 是否有效 */
    private _isValid: boolean = true;

    /**
     * 创建一个新的多边形实例
     */
    constructor() {
        this._parent = null;
        this._holes = [];
        this._isValid = true;
    }

    /**
     * 拷贝构造函数
     * @returns {Polygon2} 多边形的深拷贝
     */
    clone(): Polygon2 {
        const polygon = new Polygon2();
        polygon._parent = this._parent;
        polygon._isValid = this._isValid;
        polygon._boundary = [...this._boundary];

        // 深拷贝孔洞
        polygon._holes = this._holes.map(hole => hole.clone());

        return polygon;
    }

    /**
     * 设置边界
     * @param curves 边界曲线数组
     */
    setBoundary(curves: Array<Curve2>) {
        this._boundary = curves;
    }

    /**
     * 添加孔洞
     * @param hole 要添加的孔洞多边形
     */
    addHole(hole: Polygon2) {
        hole._parent = this;
        this._holes.push(hole);
    }

    /**
     * 移除孔洞
     * @param hole 要移除的孔洞多边形
     */
    removeHole(polygon: Polygon2) {
        const index = this._holes.indexOf(polygon);
        if (index !== -1) {
            this._holes.splice(index, 1);
        }
    }

    /**
     * 获取父多边形
     */
    getParent(): Polygon2 | null {
        return this._parent;
    }

    /**
     * 获取边界
     */
    getBoundary(): Array<Curve2> {
        return this._boundary;
    }

    /**
     * 获取孔洞
     */
    getHoles(): Array<Polygon2> {
        return this._holes;
    }

    /**
     * 获取是否有效
     */
    isValid(): boolean {
        return this._isValid;
    }

    /**
     * 设置是否有效
     */
    setValid(valid: boolean) {
        this._isValid = valid;
    }

    /**
     * 判断点是否在多边形内
     */
    containsPoint(point: Point2): boolean {
        // 射线法判断点是否在边界内
        let inside = false;
        for (const curve of this._boundary) {
            const intersections = curve.intersect(new Segment2(point, new Point2(1e6, point.y)));
            inside = intersections.intersectPoints.length % 2 === 1;
        }

        if (!inside) {
            return false;
        }

        // 检查是否在孔洞内
        for (const hole of this._holes) {
            if (hole.containsPoint(point)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取多边形内的随机点
     */
    getRandomPoint(): Point2 {
        // 获取边界曲线上的随机点
        const curve = this._boundary[0];
        const parameter = Math.random();
        return curve.d0(parameter);
    }
}